/*
 * DrawingPanel2.java
 *
 * Created on December 1, 2007, 10:20 PM
 */
//NOTES have icons follow new points, send less = less lag
//SET REPAINT TO YEAH
/**
 *
 * @author  Brian
 */
import java.awt.image.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
import java.awt.geom.AffineTransform;
import javax.imageio.ImageIO;
import java.lang.Math.*;


public class DrawingPanel2 extends javax.swing.JPanel implements MouseListener, MouseMotionListener{
    Image img;
    Image icon;
    BufferedImage imgT = null; //delete
    int moveMode = -1;
    int xOffset = -879; int tempXOffset = -1;
    int yOffset = -879; int tempYOffset = -1;
    private ArrayList iconList;
    int selectedIcon=-1; //ID within iconlist
    int iconSX, iconSY; //send variables
    
    int hx,hy;
    int width, height;
    Color penColor = Color.black; //white is erase
    int penSize = 3;
    
    boolean shiftHeld = false;
    int shiftX = -1;
    int shiftY = -1;
    
    String lineStorage = "";
    int lineCounter = 0; //If reaches 100 then send data out... or send data when mouse released
    int sendPointX = -1; int sendPointY=-1;

    public int sendX, sendY, sendHx, sendHy;
    protected int gridSize = 40; //Adjust wipes board as well

    public String getCenterOffsets(){
        int w = this.getHeight();
        int h = this.getWidth();
        w = w/-2;
        h = h/-2;
        w = w + xOffset;
        h = h + yOffset;
        return w+":"+h;
    }

    public void mousePressed(MouseEvent e) {
        sendPointX = e.getX() - xOffset;
        sendPointY = e.getY() - yOffset;
        if(SwingUtilities.isMiddleMouseButton(e)){
            shiftHeld = true;
        }
        if(SwingUtilities.isRightMouseButton(e)){ //Map re-adjustment
            tempXOffset = e.getX() + xOffset;
            tempYOffset = e.getY() + yOffset;
        }
    }
    public void mouseMoved(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {
        tempXOffset = -1;
        tempYOffset = -1;
        lineCounter = 1000; //trigger send 
        if(SwingUtilities.isMiddleMouseButton(e)){
            shiftHeld = false;
            shiftX = -1;
            shiftY = -1;
        }
        int x = e.getX();
        int y = e.getY();
        hx=0; hy=0;
        if(selectedIcon != -1){
            icon sib = (icon)iconList.get(selectedIcon);
            iconSX = sib.getX()+sib.size/2; iconSY = sib.getY()+sib.size/2;
        }
        //selectedIcon = -1;
    }
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseClicked(MouseEvent e) {}
    public int abso(int x){
        if (x<0){
            return x*-1;
        }
        return x;
    }
    public void mouseDragged(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();
        if(tempXOffset != -1 || tempYOffset != -1){
            xOffset = (tempXOffset-e.getX());
            yOffset = (tempYOffset-e.getY());
            if (xOffset>0) xOffset = 0;
            if (xOffset<-(2539-this.getWidth())) xOffset = -(2539-this.getWidth());
            if (yOffset>0) yOffset = 0;
            if (yOffset<-(2539-this.getHeight())) yOffset = -(2539-this.getHeight());
            //tempXOffset = -1;
            //tempYOffset = -1;
            repaint();
        }
        if(moveMode == -1 && tempXOffset == -1 && tempYOffset == -1){
            Graphics g = img.getGraphics();
          
            //sendX=0;sendY=0;sendHx=0;sendHy=0;
            //lineStorage = "";
            int lessX; int greatX;
            if (x<hx){
                    lessX = x; greatX = hx;
            }else{
                    lessX = hx; greatX = x;
            }
            if(lessX!=0){
                if(shiftHeld == true && shiftX == -1 && shiftY == -1){
                    shiftX = x;
                    shiftY = y;
                }
                if(shiftHeld == false){
                    shiftX = -1;
                    shiftY = -1;
                }         
                
                    int difX = shiftX - x;
                    int difY = shiftY - y;
                    if (abso(difX) > 3 || abso(difY) > 3){
                        if(shiftX != -1 && shiftY != -1){
                            if (abso(difX) < abso(difY)){
                                shiftY = -1;
                            }else{
                                shiftX = -1;
                            }
                        }
                    }
                        if (shiftX != -1 && shiftY == -1){
                            x = shiftX;
                            hx = shiftX;
                            shiftY = -1;
                        }

                        if (shiftY != -1 && shiftX == -1){
                            y = shiftY;
                            hy = shiftY;
                            shiftX = -1;
                        }
                    if(lineStorage == ""){
                        lineStorage += (x-xOffset) + "," + (y-yOffset);// + "," + (hx-xOffset) + "," + (hy-yOffset);
                    }else{
                        lineStorage += ":" + (x-xOffset) + "," + (y-yOffset);// + "," + (hx-xOffset) + "," + (hy-yOffset);
                    }
                    //lineCounter += 1;

                    setThickLine(g,penSize);
                    g.setColor(penColor);
                    g.drawLine(x-xOffset,y-yOffset,hx-xOffset,hy-yOffset);
                    paintGrid(g,gridSize);
                    int tX, tY, tW, tH;
                    if (x<hx){
                        tX = x;
                        tW = hx-x;
                    }else{
                        tX = hx;
                        tW = x-hx;
                    }
                    if (y<hy){
                        tY = y;
                        tH = hy-y;
                    }else{
                        tY = hy;
                        tH = y-hy;
                    }
                    repaint(tX-penSize,tY-penSize,tW+penSize*2,tH+penSize*2);
            }
            hx = x;
            hy = y;
        }else{
            if(selectedIcon == -1){
                for(int i=0; i<iconList.size();i++){
                    icon sib = (icon)iconList.get(i);
                    int y2 = (y-yOffset)-sib.size/2-(sib.getY());
                    int x2 = (x-xOffset)-sib.size/2-(sib.getX());
                    double dist = Math.sqrt( x2*x2 + y2*y2 );
                    if (dist <= gridSize/2){
                        selectedIcon = i;
                    }
                }
            }else{
                icon sib = (icon)iconList.get(selectedIcon);
                sib.setCoordinates(x-xOffset,y-yOffset);
                //iconSX = x; iconSY = y;
            }
        }
    }
    public void wipeGrid(int gSize){
        gridSize=gSize;
        Graphics g = img.getGraphics();
        g.setColor(Color.white);
        g.fillRect(0,0,width,height);
        paintGrid(g, gridSize);
        g.dispose();
        g.drawImage(img, 0, 0, this);
        iconList.clear();
        
        repaint();
    }
     public void moveIcon(int x, int y, int id){
        icon sib = (icon)iconList.get(id);
        sib.setCoordinates(x,y);
    }
    public int setEraseMode(){
        if(penColor==Color.black){
            penColor=Color.WHITE;
            penSize=22;
        }else{
            penColor=Color.BLACK;
            penSize=3;
        }
        return penSize;
    }
    public int setEraseMode(Color color){
        penColor = color;
        if(penColor==Color.black){
            penSize=3;
        }else{
            penSize=22;
        }
        return penSize;
    }
    public void setBrushSize(Object size){
        String sSize = (String)size;
        penSize = Integer.valueOf(sSize).intValue();
    }

    public BufferedImage makeColorTransparent(BufferedImage image, Color color) { 
        BufferedImage dimg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);  
        Graphics2D g = dimg.createGraphics();  
        g.setComposite(AlphaComposite.Src);  
        g.drawImage(image, null, 0, 0);  
        g.dispose();
        g = dimg.createGraphics();  
        g.setComposite(AlphaComposite.Src);  
        g.drawImage(image, null, 0, 0);  
        g.dispose();  
        for(int i = 0; i < dimg.getHeight(); i++) {  
            for(int j = 0; j < dimg.getWidth(); j++) {  
                if(dimg.getRGB(j, i) == color.getRGB()) {  
                    dimg.setRGB(j, i, 0x8F1C1C);  
                }  
            }  
        }
        return dimg;
    }
    public void paintComponent(Graphics g){
            super.paintComponent(g);
          
            if(img == null) {
                img = createImage(width, height);
                g = img.getGraphics();
                g.setColor(Color.white);
                g.fillRect(0,0,width,height);
                paintGrid(g, gridSize);
                g.dispose();
                repaint();
            }
            g.drawImage(img, 0+xOffset, 0+yOffset, this);
            //Graphics2D g2D = (Graphics2D)icon.getGraphics();
            //g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
            if(iconList!=null){
                for(int i=0; i<iconList.size();i++){
                    icon sib = (icon)iconList.get(i);
                    g.setColor( Color.black );
                    String s = sib.getOwner();
                    int len = g.getFontMetrics().stringWidth(sib.getOwner());
                    g.fillRect(sib.getX()-(len/2)+(sib.size/2)+xOffset,sib.getY()+sib.size+yOffset,len,10);
                    g.setColor( Color.red );
                    g.drawString(sib.getOwner(), sib.getX()-(len/2)+(sib.size/2)+xOffset, sib.getY()+sib.size+10+yOffset);
                }
            }
            if(iconList!=null){
                for(int i=0; i<iconList.size();i++){
                    icon sib = (icon)iconList.get(i);
                    g.fillOval(sib.getX()+3+xOffset, sib.getY()+3+yOffset, sib.size-6, sib.size-6);
                    g.drawImage(sib.getImg(), sib.getX()+xOffset, sib.getY()+yOffset,this);
                }
            }
    }
    public void paintGrid(Graphics g, int gridSize){
            g.setColor( Color.black );
            setThickLine(g,1);
            for(int x=10; x<width; x+=gridSize){
                    g.drawLine(x,0,x,3333);
            }
            for(int y=10; y<height; y+=gridSize){
                    g.drawLine(0,y,3333,y);
            }
    }
    public void setThickLine(Graphics g, int width){
            Graphics2D g2d = (Graphics2D)g;
        g2d.setStroke(new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    }
    /** Creates new form DrawingPanel2 */
    public DrawingPanel2() {
        addMouseListener(this);
        addMouseMotionListener(this);

        width = 3000;
        height = 3000;
        this.setPreferredSize(new Dimension(740, 300));
        iconList = new ArrayList();
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {

    }// </editor-fold>//GEN-END:initComponents
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
    public void addIcon(int iX, int iY, String imageURL, String iOwnerName){
        icon in = new icon(iX, iY, imageURL, iOwnerName, gridSize);
        iconList.add(in);
        repaint();
    }
    class icon{
        private int x,y;
        private int gotoX, gotoY;
        private BufferedImage img = null;
        private String ownerName;
        public int size;
        
        icon(int iX, int iY, String imageURL, String iOwnerName, int iSize){
            x=iX; y=iY;
            ownerName = iOwnerName;
            size = iSize;
            try{
                img = ImageIO.read(new File("images/"+imageURL));
                double newSize = size;
                double resize = newSize/300;
                ImageResizer r = new ImageResizer(img,resize);
                img = r.getResizedImage(); 
                img = makeColorTransparent(img, Color.BLACK);
            }catch(IOException e){}
        }
        public void setCoordinates(int iX, int iY){
            x = iX-size/2; y = iY-size/2;
            repaint();
            //gotoX = iX; gotoY = iY;
            //repaint(iX-70, iY-30, size+140, size+30);
        }
        public String getOwner(){ return ownerName; }
        public int getX(){ return x; }
        public int getY(){ return y; }
        public BufferedImage getImg(){ return img; }
    }
}
class ImageResizer 
{
    private BufferedImage imageToResize;
    private double factor;
    private GraphicsConfiguration gc;
	
	
    public ImageResizer(BufferedImage image, double scale)
    {
	imageToResize = image;
	factor = scale;
	gc = getDefaultConfiguration();
    }
	
    public BufferedImage getResizedImage()
    {
	return getScaledInstance();
    }
	
	
    public BufferedImage copy(BufferedImage target, Object interpolationHint) 
    {
        Graphics2D g = target.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, interpolationHint);
        double scalex = (double) target.getWidth() / imageToResize.getWidth();
        double scaley = (double) target.getHeight() / imageToResize.getHeight();
 	AffineTransform at = AffineTransform.getScaleInstance(scalex, scaley);
        g.drawRenderedImage(imageToResize, at);
        g.dispose();
        return target;
	
    }
 
    public BufferedImage getScaledInstance2D(Object interpolationHint) 
    {
        int w = (int) (imageToResize.getWidth() * factor);
        int h = (int) (imageToResize.getHeight() * factor);
        int transparency = imageToResize.getColorModel().getTransparency();
        return copy(gc.createCompatibleImage(w, h, transparency), interpolationHint);
    }
	
    public BufferedImage getScaledInstanceAWT(int hint) 
    {
	int w = (int) (imageToResize.getWidth() * factor);
        int h = (int) (imageToResize.getHeight() * factor);      
        Image image = imageToResize.getScaledInstance(w, h, hint);
	BufferedImage result = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
	Graphics2D g = result.createGraphics();
	g.drawImage(image, 0, 0, null);
	g.dispose();
	return result;
    }
 
 
public BufferedImage getScaledInstance() 
    {
        if (factor >= 1.0)
		return getScaledInstance2D(RenderingHints.VALUE_INTERPOLATION_BICUBIC);
       else
		return getScaledInstanceAWT(Image.SCALE_AREA_AVERAGING);
    }
 
 public GraphicsConfiguration getDefaultConfiguration() 
    {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        return gd.getDefaultConfiguration();
    }
}
